package com.wang.learrn.common.mybatis.handler;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.util.ClassUtils;

import java.nio.charset.Charset;
import java.time.LocalDateTime;

/**
 * @author : wcz
 * @version V1.0
 * @Description: 对于固定字段的插入与更新时的处理
 */
@Slf4j
public class BaseMetaObjectHandler implements MetaObjectHandler {

    private static final String CREATE_TIME = "create_time";
    private static final String CREATE_USER = "create_user";
    private static final String UPDATE_USER = "update_user";
    private static final String UPDATE_TIME = "update_time";

    //该字段配置在TenantMapper中
//    private static final String TENANT_ID = "tenant_id";

    @Override
    public void insertFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();

        fillValIfNullByName(CREATE_TIME,now,metaObject,false);
        fillValIfNullByName(UPDATE_TIME,now,metaObject,false);
        fillValIfNullByName(CREATE_USER,getUserId(),metaObject,false);
        fillValIfNullByName(UPDATE_USER,getUserId(),metaObject,false);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        fillValIfNullByName(UPDATE_TIME,now,metaObject,false);
        fillValIfNullByName(UPDATE_USER,getUserId(),metaObject,false);
    }

    /**
     *
     *
     * @param fieldName Entity中的属性名
     * @param fieldVal 要赋值给属性的值
     * @param metaObject MP中的元数据类型
     * @param coverFlag 是否要覆盖的标识 true 表示需要覆盖，false表示不需要覆盖
     */
    private static void fillValIfNullByName(String fieldName,Object fieldVal,MetaObject metaObject,boolean coverFlag){
        //没有setter方法
        if(!metaObject.hasSetter(fieldName)){
            log.debug("entity filed:"+fieldName+"don't have setter method");

            return;
        }

        //根据属性名获取属性值
        Object value = metaObject.getValue(fieldName);
        String str = StrUtil.str(value, Charset.defaultCharset());
        //数据不为null 并且不需要覆盖时不做任何操作
        if (StrUtil.isNotBlank(str)&& !coverFlag){
            return ;
        }

        // 3. 当属性与值的类型相同时设置
        Class<?> getterType = metaObject.getGetterType(fieldName);
        if(ClassUtils.isAssignableValue(getterType,fieldVal)){
            metaObject.setValue(fieldName,fieldVal);
        }

    }

    /**
     * 获取用户的Id
     *
     * @return 用户Id
     */
    private Long getUserId(){
        //TODO 根据认证框架获取用户Id
        return 1000L;
    }


}
